﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Data.OleDb;
using System.Data;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
// [System.Web.Script.Services.ScriptService]

public class Service : System.Web.Services.WebService
{
    private static string connectionString = "Provider=Microsoft.JET.OLEDB.4.0; Data Source=" +
        HttpContext.Current.Server.MapPath("~/App_Data/Bank.mdb");

    public Service () {

        //Uncomment the following line if using designed components 
        //InitializeComponent(); 
    }

    [WebMethod]
    public string HelloWorld() {
        return "Hello World";
    }

    // Mã trả về:
    // 0 : Thanh toán thành công
    private const int SUCCESS = 0;
    // 1 : Thông tin thanh toán ko phù hợp / ko tìm thấy thẻ
    private const int CC_NOT_FOUND = 1;
    // 2 : Thẻ ko đủ tiền
    private const int NOT_ENOUGH_MONEY = 2;
    // 3 : Server lỗi
    private const int SERVER_ERROR = 3;
    
    // Type : 1-amex, 2-visa, 3-master
    [WebMethod]
    public int Pay(int cardType, string cardNumber, string CVV, 
        int monthExpires, int yearExpires, decimal totalPayment)
    {
        DateTime now = DateTime.Now;
        // kiểm tra thông tin vào hợp lệ
        if (cardType<=0 || cardNumber == null || CVV == null || monthExpires < 1 || monthExpires > 12 
            || yearExpires < now.Year || (yearExpires == now.Year && monthExpires<now.Month)
            || totalPayment < 0) return CC_NOT_FOUND;

        OleDbConnection connection = new OleDbConnection();
        try
        {
            // tạo đối tượng connection và khởi tạo transaction 
            connection.ConnectionString =  connectionString;
            connection.Open();
            OleDbTransaction transaction = connection.BeginTransaction();
            
            bool success = false;
            try
            {
                    // tạo command và thiết lập lệnh truy vấn
                OleDbCommand command = new OleDbCommand();
                command.Connection = connection;
                command.CommandType = CommandType.Text;
                // ko khóa được xlock trên access :(( --- CreditCard with(xlock)
                string commandText = "select * from CreditCard where Type=@cardType and Number=@cardNumber "
                    + "and CVV=@CVV and MonthExpires=@monthExpires and YearExpires=@yearExpires";
                command.CommandText = commandText;
                command.Parameters.Add(new OleDbParameter("@cardType", cardType));
                command.Parameters.Add(new OleDbParameter("@cardNumber", cardNumber));
                command.Parameters.Add(new OleDbParameter("@CVV", CVV));
                command.Parameters.Add(new OleDbParameter("@monthExpires", monthExpires));
                command.Parameters.Add(new OleDbParameter("@yearExpires", yearExpires));
                command.Transaction = transaction;

                // tạo đối tượng DataAdapter để đọc về bảng dữ liệu
                OleDbDataAdapter adapter = new OleDbDataAdapter(command);
                DataTable table=new DataTable();
                adapter.Fill(table);

                if (table.Rows.Count != 1) return CC_NOT_FOUND;
                if ((decimal)table.Rows[0]["Balance"] < totalPayment) return NOT_ENOUGH_MONEY;

                // ok, đủ tiền, tiến hành thanh toán
                OleDbCommand write = new OleDbCommand();
                write.Connection = connection;
                write.CommandType = CommandType.Text;
                commandText = "update CreditCard set Balance=Balance-@totalPayment "
                        + " where ID=" + table.Rows[0]["ID"];
                write.CommandText = commandText;
                write.Parameters.Add(new OleDbParameter("@totalPayment", totalPayment));
                write.Transaction = transaction;
                
                if (write.ExecuteNonQuery() <= 0) return SERVER_ERROR;
                
                transaction.Commit();
                success = true;
            }
            catch (System.Exception err)
            {
                return SERVER_ERROR;
            }
            finally
            {
                if(!success)
                    transaction.Rollback();
            }
        }
        catch (System.Exception)
        {
            return SERVER_ERROR;
        }
        finally
        {
            if (connection.State == ConnectionState.Open) connection.Close();
        }
        
        return SUCCESS;
    }
}